package br.iars.model.context.impl;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import br.iars.model.context.ContextDataModel;
import br.iars.model.entity.Context;
import br.iars.model.entity.Item;
import br.iars.model.entity.User;
import br.iars.model.exception.PersistenceException;

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ContextDataModelImpl implements ContextDataModel {

	@PersistenceContext(unitName = "recommendation-system-pu")
	private EntityManager entityManager;

	public Item load(Item item) throws PersistenceException {

		if ((item.getId() == null || item.getId() == 0) && (item.getCode() == null || item.getCode() == 0)) {
			throw new PersistenceException("Invalid filter!");
		}

		try {
			StringBuilder jpql = new StringBuilder();
			jpql.append("FROM Item i WHERE ");

			String and = "";

			if (item.getId() != null && item.getId() > 0) {
				jpql.append("i.id = :itemId");
				and = " AND ";
			}
			if (item.getCode() != null && item.getCode() > 0) {
				jpql.append(and + "i.code = :itemCode");
				and = " AND ";
			}
			if (item.getContext() != null && item.getContext().getId() != null && item.getContext().getId() > 0) {
				jpql.append(and + "i.context.id = :contextId");
				and = "";
			}

			Query query = entityManager.createQuery(jpql.toString());

			if (item.getId() != null && item.getId() > 0) {
				query.setParameter("itemId", item.getId());
			}
			if (item.getCode() != null && item.getCode() > 0) {
				query.setParameter("itemCode", item.getCode());
			}
			if (item.getContext() != null && item.getContext().getId() != null && item.getContext().getId() > 0) {
				query.setParameter("contextId", item.getContext().getId());
			}

			return (Item) query.getSingleResult();
		} catch (NoResultException e) {
			return null;
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}

	public User load(User user) throws PersistenceException {
		if (user == null)
			return null;
		
		try {
			StringBuilder jpql = new StringBuilder();
			jpql.append("FROM User u WHERE ");

			if (user.getId() != null && user.getId() > 0){
				jpql.append("u.id = :userId");
			} else if(user.getEmail() != null && !user.getEmail().trim().isEmpty())  {
				jpql.append("u.email = :email");
			}
			
			Query query = entityManager.createQuery(jpql.toString());
			
			if (user.getId() != null && user.getId() > 0){
				query.setParameter("userId", user.getId());
			} else if(user.getEmail() != null && !user.getEmail().trim().isEmpty())  {
				query.setParameter("email", user.getEmail());
			}

			return (User) query.getSingleResult();
		} catch (NoResultException e) {
			return null;
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}

	public Context load(Context context) throws PersistenceException {
		try {
			StringBuilder jpql = new StringBuilder();
			jpql.append("FROM Context c WHERE c.companyName = :companyName AND c.systemName = :systemName");

			Query query = entityManager.createQuery(jpql.toString());
			query.setParameter("companyName", context.getCompanyName());
			query.setParameter("systemName", context.getSystemName());

			return (Context) query.getSingleResult();
		} catch (NoResultException e) {
			return null;
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}

	public Item insert(Item item) throws PersistenceException {
		try {
			entityManager.persist(item);
			return item;
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}

	public User insert(User user) throws PersistenceException {
		try {
			entityManager.persist(user);
			return user;
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}

	public Context insert(Context context) throws PersistenceException {
		try {
			entityManager.persist(context);
			return context;
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}
	
	public Context update(Context context) throws PersistenceException {
		try {
			return entityManager.merge(context);			
		} catch (Exception e) {
			throw new PersistenceException("", e);
		}
	}

}
